package remoting
{
	
	import flash.net.Responder;
	import flash.utils.Timer;
	import flash.events.*;
	
	import log.Logger;
	
	/**
	 * -- Command --
	 * @desc	used to call server methods
	 * @author	Aqua (built on 2011-11-15)
	 */
	public class Command
	{
		//---------------------//
		//     Constructor     //
		//---------------------//
		
		/**************************************************************************
		 * -- Command --
		 * @desc		constructor
		 * @param		(command) name of the command
		 * @param		(response) response function on success
		 * @param		(param) param of the command
		 * @param		(callServerMethod) function used to call server method
		 *************************************************************************/
		public function Command(command:String, response:Function, param:Object, callServerMethod:Function):void
		{
			_command	= command;
			_response	= response;
			_param		= param;
			_call		= callServerMethod;
			
			_timer = new Timer(TIME_OUT);
			_timer.addEventListener(TimerEvent.TIMER, onTimer);
		}
		
		
		//-----------------//
		//     Publics     //
		//-----------------//
		
		/**************************************************************************
		 * -- excute --
		 * @desc		excute the command
		 *************************************************************************/
		public function excute():void
		{
			var rsp:Responder;
			
			rsp = new Responder(onSuccess, onFail);
			_call(_command, rsp, _param);
			_timer.start();
		}
		
		
		//------------------//
		//     Privates     //
		//------------------//
		
		/**************************************************************************
		 * -- onSuccess --
		 * @desc		success handler when calling php method
		 * @param		(returnValue) return value from server
		 *************************************************************************/
		private function onSuccess(returnValue:Object):void
		{
			Logger.log("success: " + _command);
			Logger.log("result: " + returnValue.result);
			destroy();
			
			switch(returnValue.result)
			{
				case Server.OPERATION_SUCCEED:
					_response(returnValue.data);
					break;
				case Server.OPERATION_FAIL:
					Server.error = Server.ERROR_OPERATION_FAIL;
					Server.popupError();
					break;
				default:
					throw new Error("Undefined result type !");
					break;
			}
		}
		
		/**************************************************************************
		 * -- onFail --
		 * @desc		failure handler when calling php method
		 * @param		(error) an object which includes error information
		 *************************************************************************/
		private function onFail(returnValue:Object):void
		{
			Logger.log("fail: " + _command);
			destroy();
			Server.error = Server.ERROR_RESPONSE_FAIL;
			Server.popupError();
		}
		
		/**************************************************************************
		 * -- onTimer --
		 * @desc		timer event handler
		 * @param		(e) event information
		 *************************************************************************/
		private function onTimer(e:TimerEvent):void
		{
			destroy();
			Server.error = Server.ERROR_TIME_OUT;
			Server.popupError();
		}
		
		/**************************************************************************
		 * -- destroy --
		 * @desc		destroy timer
		 *************************************************************************/
		private function destroy():void
		{
			_timer.stop();
			_timer.removeEventListener(TimerEvent.TIMER, onTimer);
		}
		
		
		private static const TIME_OUT	:int = 300000;	// 5 min
		
		private static var _timer		:Timer;
		private static var _command		:String;
		private static var _response	:Function;
		private static var _param		:Object;
		private static var _call		:Function;
	}
	
}